home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 15 / CU Amiga Magazine's Super CD-ROM 15 (1997)(EMAP Images)(GB)[!][issue 1997-10].iso / CUCD / Graphics / Ghostscript / source / libpng / pngwtran.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-15  |  10.8 KB  |  393 lines

  1.  
  2. /* pngwtran.c - transforms the data in a row for PNG writers
  3.  
  4.    libpng 1.0 beta 6 - version 0.96
  5.    For conditions of distribution and use, see copyright notice in png.h
  6.    Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  7.    Copyright (c) 1996, 1997 Andreas Dilger
  8.    May 12, 1997
  9.    */
  10.  
  11. #define PNG_INTERNAL
  12. #include "png.h"
  13.  
  14. /* transform the data according to the users wishes.  The order of
  15.    transformations is significant. */
  16. void
  17. png_do_write_transformations(png_structp png_ptr)
  18. {
  19.    png_debug(1, "in png_do_write_transformations\n");
  20. #if defined(PNG_WRITE_FILLER_SUPPORTED)
  21.    if (png_ptr->transformations & PNG_FILLER)
  22.       png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
  23.          png_ptr->flags);
  24. #endif
  25. #if defined(PNG_WRITE_PACK_SUPPORTED)
  26.    if (png_ptr->transformations & PNG_PACK)
  27.       png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1,
  28.          (png_uint_32)png_ptr->bit_depth);
  29. #endif
  30. #if defined(PNG_WRITE_SHIFT_SUPPORTED)
  31.    if (png_ptr->transformations & PNG_SHIFT)
  32.       png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1,
  33.          &(png_ptr->shift));
  34. #endif
  35. #if defined(PNG_WRITE_SWAP_SUPPORTED)
  36.    if (png_ptr->transformations & PNG_SWAP_BYTES)
  37.       png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
  38. #endif
  39. #if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
  40.    if (png_ptr->transformations & PNG_SWAP_ALPHA)
  41.       png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
  42. #endif
  43. #if defined(PNG_WRITE_BGR_SUPPORTED)
  44.    if (png_ptr->transformations & PNG_BGR)
  45.       png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
  46. #endif
  47. #if defined(PNG_WRITE_INVERT_SUPPORTED)
  48.    if (png_ptr->transformations & PNG_INVERT_MONO)
  49.       png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
  50. #endif
  51. }
  52.  
  53. #if defined(PNG_WRITE_PACK_SUPPORTED)
  54. /* pack pixels into bytes.  Pass the true bit depth in bit_depth.  The
  55.    row_info bit depth should be 8 (one pixel per byte).  The channels
  56.    should be 1 (this only happens on grayscale and paletted images) */
  57. void
  58. png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
  59. {
  60.    png_debug(1, "in png_do_pack\n");
  61.    if (row_info->bit_depth == 8 &&
  62. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  63.        row != NULL && row_info != NULL &&
  64. #endif
  65.       row_info->channels == 1)
  66.    {
  67.       switch ((int)bit_depth)
  68.       {
  69.          case 1:
  70.          {
  71.             png_bytep sp, dp;
  72.             int mask, v;
  73.             png_uint_32 i;
  74.  
  75.             sp = row;
  76.             dp = row;
  77.             mask = 0x80;
  78.             v = 0;
  79.             for (i = 0; i < row_info->width; i++)
  80.             {
  81.                if (*sp != 0)
  82.                   v |= mask;
  83.                sp++;
  84.                if (mask > 1)
  85.                   mask >>= 1;
  86.                else
  87.                {
  88.                   mask = 0x80;
  89.                   *dp = (png_byte)v;
  90.                   dp++;
  91.                   v = 0;
  92.                }
  93.             }
  94.             if (mask != 0x80)
  95.                *dp = (png_byte)v;
  96.             break;
  97.          }
  98.          case 2:
  99.          {
  100.             png_bytep sp, dp;
  101.             int shift, v;
  102.             png_uint_32 i;
  103.  
  104.             sp = row;
  105.             dp = row;
  106.             shift = 6;
  107.             v = 0;
  108.             for (i = 0; i < row_info->width; i++)
  109.             {
  110.                png_byte value;
  111.  
  112.                value = (png_byte)(*sp & 0x3);
  113.                v |= (value << shift);
  114.                if (shift == 0)
  115.                {
  116.                   shift = 6;
  117.                   *dp = (png_byte)v;
  118.                   dp++;
  119.                   v = 0;
  120.                }
  121.                else
  122.                   shift -= 2;
  123.                sp++;
  124.             }
  125.             if (shift != 6)
  126.                *dp = (png_byte)v;
  127.             break;
  128.          }
  129.          case 4:
  130.          {
  131.             png_bytep sp, dp;
  132.             int shift, v;
  133.             png_uint_32 i;
  134.  
  135.             sp = row;
  136.             dp = row;
  137.             shift = 4;
  138.             v = 0;
  139.             for (i = 0; i < row_info->width; i++)
  140.             {
  141.                png_byte value;
  142.  
  143.                value = (png_byte)(*sp & 0xf);
  144.                v |= (value << shift);
  145.  
  146.                if (shift == 0)
  147.                {
  148.                   shift = 4;
  149.                   *dp = (png_byte)v;
  150.                   dp++;
  151.                   v = 0;
  152.                }
  153.                else
  154.                   shift -= 4;
  155.  
  156.                sp++;
  157.             }
  158.             if (shift != 4)
  159.                *dp = (png_byte)v;
  160.             break;
  161.          }
  162.       }
  163.       row_info->bit_depth = (png_byte)bit_depth;
  164.       row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
  165.       row_info->rowbytes =
  166.          ((row_info->width * row_info->pixel_depth + 7) >> 3);
  167.    }
  168. }
  169. #endif
  170.  
  171. #if defined(PNG_WRITE_SHIFT_SUPPORTED)
  172. /* shift pixel values to take advantage of whole range.  Pass the
  173.    true number of bits in bit_depth.  The row should be packed
  174.    according to row_info->bit_depth.  Thus, if you had a row of
  175.    bit depth 4, but the pixels only had values from 0 to 7, you
  176.    would pass 3 as bit_depth, and this routine would translate the
  177.    data to 0 to 15. */
  178. void
  179. png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
  180. {
  181.    png_debug(1, "in png_do_shift\n");
  182. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  183.    if (row != NULL && row_info != NULL &&
  184. #else
  185.    if (
  186. #endif
  187.       row_info->color_type != PNG_COLOR_TYPE_PALETTE)
  188.    {
  189.       int shift_start[4], shift_dec[4];
  190.       png_uint_32 channels;
  191.  
  192.       channels = 0;
  193.       if (row_info->color_type & PNG_COLOR_MASK_COLOR)
  194.       {
  195.          shift_start[channels] = row_info->bit_depth - bit_depth->red;
  196.          shift_dec[channels] = bit_depth->red;
  197.          channels++;
  198.          shift_start[channels] = row_info->bit_depth - bit_depth->green;
  199.          shift_dec[channels] = bit_depth->green;
  200.          channels++;
  201.          shift_start[channels] = row_info->bit_depth - bit_depth->blue;
  202.          shift_dec[channels] = bit_depth->blue;
  203.          channels++;
  204.       }
  205.       else
  206.       {
  207.          shift_start[channels] = row_info->bit_depth - bit_depth->gray;
  208.          shift_dec[channels] = bit_depth->gray;
  209.          channels++;
  210.       }
  211.       if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
  212.       {
  213.          shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
  214.          shift_dec[channels] = bit_depth->alpha;
  215.          channels++;
  216.       }
  217.  
  218.       /* with low row dephts, could only be grayscale, so one channel */
  219.       if (row_info->bit_depth < 8)
  220.       {
  221.          png_bytep bp;
  222.          png_uint_32 i;
  223.          png_byte mask;
  224.  
  225.          if (bit_depth->gray == 1 && row_info->bit_depth == 2)
  226.             mask = 0x55;
  227.          else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
  228.             mask = 0x11;
  229.          else
  230.             mask = 0xff;
  231.  
  232.          for (bp = row, i = 0; i < row_info->rowbytes; i++, bp++)
  233.          {
  234.             png_uint_16 v;
  235.             int j;
  236.  
  237.             v = *bp;
  238.             *bp = 0;
  239.             for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
  240.             {
  241.                if (j > 0)
  242.                   *bp |= (png_byte)((v << j) & 0xff);
  243.                else
  244.                   *bp |= (png_byte)((v >> (-j)) & mask);
  245.             }
  246.          }
  247.       }
  248.       else if (row_info->bit_depth == 8)
  249.       {
  250.          png_bytep bp;
  251.          png_uint_32 i;
  252.  
  253.          for (bp = row, i = 0; i < row_info->width; i++)
  254.          {
  255.             int c;
  256.  
  257.             for (c = 0; c < channels; c++, bp++)
  258.             {
  259.                png_uint_16 v;
  260.                int j;
  261.  
  262.                v = *bp;
  263.                *bp = 0;
  264.                for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
  265.                {
  266.                   if (j > 0)
  267.                      *bp |= (png_byte)((v << j) & 0xff);
  268.                   else
  269.                      *bp |= (png_byte)((v >> (-j)) & 0xff);
  270.                }
  271.             }
  272.          }
  273.       }
  274.       else
  275.       {
  276.          png_bytep bp;
  277.          png_uint_32 i;
  278.  
  279.          for (bp = row, i = 0; i < row_info->width * row_info->channels; i++)
  280.          {
  281.             int c;
  282.  
  283.             for (c = 0; c < channels; c++, bp += 2)
  284.             {
  285.                png_uint_16 value, v;
  286.                int j;
  287.  
  288.                v = ((png_uint_16)(*bp) << 8) + *(bp + 1);
  289.                value = 0;
  290.                for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
  291.                {
  292.                   if (j > 0)
  293.                      value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
  294.                   else
  295.                      value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
  296.                }
  297.                *bp = (png_byte)(value >> 8);
  298.                *(bp + 1) = (png_byte)(value & 0xff);
  299.             }
  300.          }
  301.       }
  302.    }
  303. }
  304. #endif
  305.  
  306. #if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
  307. void
  308. png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
  309. {
  310.    png_debug(1, "in png_do_write_swap_alpha\n");
  311. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  312.    if (row != NULL && row_info != NULL)
  313. #endif
  314.    {
  315.       if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
  316.       {
  317.          /* This converts from ARGB to RGBA */
  318.          if (row_info->bit_depth == 8)
  319.          {
  320.             png_bytep sp, dp;
  321.             png_byte save;
  322.             png_uint_32 i;
  323.  
  324.             for (i = 0, sp = dp = row; i < row_info->width; i++)
  325.             {
  326.                save = *(sp++);
  327.                *(dp++) = *(sp++);
  328.                *(dp++) = *(sp++);
  329.                *(dp++) = *(sp++);
  330.                *(dp++) = save;
  331.             }
  332.          }
  333.          /* This converts from AARRGGBB to RRGGBBAA */
  334.          else
  335.          {
  336.             png_bytep sp, dp;
  337.             png_byte save[2];
  338.             png_uint_32 i;
  339.  
  340.             for (i = 0, sp = dp = row; i < row_info->width; i++)
  341.             {
  342.                save[0] = *(sp++);
  343.                save[1] = *(sp++);
  344.                *(dp++) = *(sp++);
  345.                *(dp++) = *(sp++);
  346.                *(dp++) = *(sp++);
  347.                *(dp++) = *(sp++);
  348.                *(dp++) = *(sp++);
  349.                *(dp++) = *(sp++);
  350.                *(dp++) = save[0];
  351.                *(dp++) = save[1];
  352.             }
  353.          }
  354.       }
  355.       else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
  356.       {
  357.          /* This converts from AG to GA */
  358.          if (row_info->bit_depth == 8)
  359.          {
  360.             png_bytep sp, dp;
  361.             png_byte save;
  362.             png_uint_32 i;
  363.  
  364.             for (i = 0, sp = dp = row; i < row_info->width; i++)
  365.             {
  366.                save = *(sp++);
  367.                *(dp++) = *(sp++);
  368.                *(dp++) = save;
  369.             }
  370.          }
  371.          /* This converts from AAGG to GGAA */
  372.          else
  373.          {
  374.             png_bytep sp, dp;
  375.             png_byte save[2];
  376.             png_uint_32 i;
  377.  
  378.             for (i = 0, sp = dp = row; i < row_info->width; i++)
  379.             {
  380.                save[0] = *(sp++);
  381.                save[1] = *(sp++);
  382.                *(dp++) = *(sp++);
  383.                *(dp++) = *(sp++);
  384.                *(dp++) = save[0];
  385.                *(dp++) = save[1];
  386.             }
  387.          }
  388.       }
  389.    }
  390. }
  391. #endif
  392.  
  393.